<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>03_迭代对象-创建可迭代对象</title>
  <!-- 
  在JavaScript中，为数组创建迭代器可以帮助我们以更灵活的方式遍历数组元素。
  1. 迭代器的基本概念
  迭代器是一个对象，提供了一个 `next()` 方法，该方法返回一个包含当前值和遍历状态的对象。每次调用 `next()` 时，都会返回数组中的下一个元素，直到数组遍历完毕。

  2. 自定义数组迭代器
  可以通过创建一个包含 `next()` 方法的对象来实现自定义数组迭代器。以下是一个简单的示例：
  function createArrayIterator(array) {
      let index = 0; // 初始化索引
      return {
          next: function() {
              if (index < array.length) {
                  return { value: array[index++], done: false }; // 返回当前值和未完成状态
              } else {
                  return { done: true }; // 遍历完成
              }
          }
      };
  }

  // 使用示例
  const myArray = [10, 20, 30];
  const iterator = createArrayIterator(myArray);

  console.log(iterator.next()); // { value: 10, done: false }
  console.log(iterator.next()); // { value: 20, done: false }
  console.log(iterator.next()); // { value: 30, done: false }
  console.log(iterator.next()); // { done: true }
  3. 使用  `Symbol.iterator` 
  JavaScript的数组对象已经内置了迭代器，可以直接使用 `Symbol.iterator` 来获取数组的迭代器：
  const myArray = [10, 20, 30];
  const arrayIterator = myArray[Symbol.iterator]();

  console.log(arrayIterator.next()); // { value: 10, done: false }
  console.log(arrayIterator.next()); // { value: 20, done: false }
  console.log(arrayIterator.next()); // { value: 30, done: false }
  console.log(arrayIterator.next()); // { done: true }
  4. 使用  `for...of`  循环
  JavaScript提供了 `for...of` 循环，可以直接遍历数组及其他可迭代对象，而无需手动调用 `next()` 方法：
  const myArray = [10, 20, 30];
  for (const value of myArray) {
      console.log(value); // 输出 10, 20, 30
  }
  5. 生成器作为迭代器
  生成器是一种特殊类型的迭代器，可以用来简化迭代器的创建过程。使用 `function*` 和 `yield` 关键字，可以轻松创建一个数组的迭代器：
  function* arrayGenerator(array) {
      for (const item of array) {
          yield item; // 暂停并返回当前值
      }
  }

  // 使用示例
  const myArray = [10, 20, 30];
  const gen = arrayGenerator(myArray);

  console.log(gen.next()); // { value: 10, done: false }
  console.log(gen.next()); // { value: 20, done: false }
  console.log(gen.next()); // { value: 30, done: false }
  console.log(gen.next()); // { done: true }
  总结
  为数组创建迭代器可以帮助我们更灵活地遍历数组元素。通过自定义迭代器、使用内置的 `Symbol.iterator` 或生成器，可以方便地实现迭代功能。这些工具在处理数据时提供了更高的可读性和可维护性。
  -->
</head>
<body>

  <script>
    // 创建可迭代对象
    // 1. 默认情况下，对象是不可迭代的
    // 2. 要创建可迭代对象，必须实现 @@iterator 方法
    // 3. @@iterator 方法是一个无参数函数，返回一个迭代器
    // 4. 迭代器是一个对象，具有一个 next 方法，该方法返回一个对象，该对象具有两个属性：value 和 done
    // 5. value 属性表示迭代器返回的值，done 属性表示迭代器是否已经迭代完所有元素
  
    // 实现可迭代对象
    /**
     * 1. 必须实现一个特定的函数: [Symbol.iterator]
     * 2. 这个函数必须返回一个迭代器对象，这个对象包含一个 next 方法, 用于迭代当前对象
     * 
    */
   const infos = {
    friends: ['张三', '李四', '王五'],
    [Symbol.iterator]() {
      return {
        next() {
          this.index = this.index || 0;
          if (this.index === infos.friends.length) {
            return {
              value: undefined,
              done: true
            }
          }
          return {
            value: infos.friends[this.index++],
            done: false
          }
        }
      }
    }
   }

   // 可迭代对象必然具备以下特点
   const iterator = infos[Symbol.iterator]();
   console.log(iterator.next());
   console.log(iterator.next());
   console.log(iterator.next());
   console.log(iterator.next());

  // 可迭代对象必然有一个[Symbol.iterator]函数
  // 数组是一个可迭代对象
   const arr = [22, 33, 55]
   const iterator2 = arr[Symbol.iterator]();
   console.log(iterator2);
   console.log(iterator2.next());
   console.log(iterator2.next());
   console.log(iterator2.next());
   console.log(iterator2.next());
   

    

  </script>
  
</body>
</html>